package DATA.iDataSetParts;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.Serializable;
import java.text.DecimalFormat;
import java.util.Vector;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 * 
 * @author Bunkowski
 */
public class Peaklist implements Serializable {

	public static final long serialVersionUID = 1L;// 7366824218502823397L;

	private String filename = "";
	// public File file;
	private Vector<Peak> peaks = new Vector<Peak>();
	private String[] header;
	public String timeStamp;
	private String Class = "";

	public Peaklist(String[] header, String timestamp, String filename) {
		this.header = header;
		this.timeStamp = timestamp;
		this.filename = filename;
	}

	public void addPeak(Peak p) {
		peaks.add(p);
	}

	public Peaklist(File file) {
		BufferedReader br;
		// this.file = file;
		try {
			br = new BufferedReader(new FileReader(file));
			String rl;
			header = br.readLine().split("\\s+");// reading header
			while ((rl = br.readLine()) != null) {
				String[] line = new String[6];
				rl = rl.trim();
				line = rl.split("\\s+");
				Peak peak = new Peak(line);
				peaks.add(peak);
			}
		} catch (FileNotFoundException e) {
			e.printStackTrace();
			System.out.println("Peaklistfile " + file.getName() + " not found.");
		} catch (IOException e) {
			e.printStackTrace();
			System.out.println("IOException opening peaklistfile " + file.getName());
		}

		filename = file.getName();
		timeStamp = file.getName().split("_")[1];
	}

	public void writeToFolder(File folderpath) {
		File file = new File(folderpath.toString() + "\\" + filename);
		try {
			BufferedWriter bw = new BufferedWriter(new FileWriter(file));
			for (String s : header) {
				bw.write(s + "\t");
			}
			bw.newLine();
			for (Peak peak : peaks) {
				for (String s : peak.getParametersAsStringVector()) {
					bw.write(s + "\t");
				}
				bw.newLine();
			}
			bw.close();
		} catch (IOException ex) {
			Logger.getLogger(Peaklist.class.getName()).log(Level.SEVERE, null, ex);
			System.out.println("Error writing Peaklist to " + folderpath.toString());
		}
	}

	/*
	 * public Peaklist(String filename,Vector<String[]> peaks) { this.filename = filename; this.peaks = peaks;
	 * this.timeStamp = filename.split("_")[1]; }
	 */
	public void scaleRt(double newscalefactor) {
		double oldscalefactor = getRtFactor();
		for (Peak peak : peaks) {
			peak.rt = peak.rt * newscalefactor;
		}
		header[2] = "rt_x" + (newscalefactor * oldscalefactor);
	}

	public String getFilename() {
		return filename;
	}

	public Vector<Peak> getPeaks() {
		return peaks;
	}
	
	
	private double parseDouble(String string){
		String commaReplaced = string.replace(",",".");
		double result = Double.parseDouble(commaReplaced);
		return result;
	}
	

	public double getRtFactor() {
		try {
			if (header[2].contains("_x")) {
				return parseDouble(header[2].split("_x")[1]);
			} else
				return 1.0;
		} catch (Exception ex) {
			return 1.0;
		}
	}

	/**
	 * 20.12.2011(Enable Rip position correction)
	 * Returns the 1/k0 offset saved in the header Designed for Rip position correction.
	 * header[1].split("_x")[1] is used for offset storage
	 * 0 if no K0 Offset was defined or any error occurred.
	 * 
	 * @return
	 */
	public double getK0Offset() {
		try {
			if (header[1].contains("_x")) {
				return parseDouble(header[1].split("_x")[1]);
			} else
				return 0;
		} catch (Exception ex) {
			System.out.println("Exception in Peaklist.java getK0Offset() :"+this.filename);
			ex.printStackTrace();
			return 0;
		}
	}

	/**
	 * 20.12.2011(Enable Rip position correction)
	 * Shifts the 1/k0 axis (x) Designed for Rip position correction 
	 * header[1].split("_x")[1] is used for offset storage.
	 * 
	 * @param newsshift
	 */
	public void shiftK0(double newsshift) {
		double oldshift = getK0Offset();
		DecimalFormat f4 = new DecimalFormat("0.0000");
		for (Peak peak : peaks) {
			peak.dt = peak.dt + newsshift;
		}
		header[1] = "1/k0_x" + f4.format(newsshift + oldshift) + "_x" + f4.format(getOriginalRipPosition());
	}
	
	public void resetK0Shift(){
		double oldshift = getK0Offset();
		double newsshift = oldshift*-1;
		
		DecimalFormat f4 = new DecimalFormat("0.0000");
		for (Peak peak : peaks) {
			peak.dt = peak.dt + newsshift;
		}
		header[1] = "1/k0_x" + f4.format(newsshift + oldshift) + "_x" + f4.format(getOriginalRipPosition());
	}

	/**
	 * 20.12.2011(Enable Rip position correction)
	 * Set the original Rip Position. Should be used during Peak list generation because Rip Position is
	 * available there. Do not change this afterwards. If needed use "shiftK0" to correct the Rip position.
	 * header[1].split("_x")[2] is used for Rip position storage
	 * 
	 * @param formatRipPosition
	 */
	public void setOriginalRipPosition(String formatRipPosition) {
		header[1] = "1/k0_x" + 0 + "_x" + formatRipPosition;
	}

	/**
	 * 20.12.2011(Enable Rip position correction)
	 * Returns the Rip position which should be defined during peak list generation.
	 * 0 if no rip position was defined or any error occurred.
	 * 
	 * @return
	 */
	public double getOriginalRipPosition() {
		try {
			if (header[1].contains("_x")) {
				return parseDouble(header[1].split("_x")[2]);
			} else
				return 0;
		} catch (Exception ex) {
			System.out.println("Exception in Peaklist.java getOriginalRipPosition()");
			return 0;
		}
	}

	public String[] getHeader() {
		return header;
	}

	public Vector<Vector<String>> getPeaksAsVector() {
		Vector<Vector<String>> peakdata = new Vector<Vector<String>>();
		for (Peak peak : peaks) {
			peakdata.add(peak.getParametersAsStringVector());
		}
		return peakdata;
	}

	public Vector<String> getDefaultHeader() {
		Vector<String> header = new Vector<String>();
		header.add("intensity");
		header.add("1/k0");
		header.add("rt");
		header.add("1/k0_size");
		header.add("rt_size");
		header.add("volume");
		return header;
	}

	public Vector<Vector<String>> getPeaksWithSubstanceAsVector() {
		Vector<Vector<String>> peakdata = new Vector<Vector<String>>();
		for (Peak peak : peaks) {
			peakdata.add(peak.getParametersAsStringVectorWithSubstance());
		}
		return peakdata;
	}

	public Vector<String> getHeaderWithSubstance() {
		Vector<String> header = new Vector<String>();
		header.add("substance");
		header.add("intensity");
		header.add("1/k0");
		header.add("rt");
		header.add("1/k0 size");
		header.add("rt size");
		header.add("volume");
		return header;
	}

	public String toString() {
		String returnValue = "";

		returnValue = "ObjClass : " + this.getClass() + "\r\n";

		returnValue += "filename : " + filename + "\r\n";
		returnValue += "timeStamp : " + timeStamp + "\r\n";
		returnValue += "Class : " + Class + "\r\n";

		String headerTxt = "";

		for (int i = 0; i < header.length; i++) {

			headerTxt += header[i] + ";";
		}
		headerTxt = headerTxt.substring(0, headerTxt.length() - 1);

		returnValue += "header : " + headerTxt + "\r\n";

		String PeakListe = "";
		returnValue += "PeaksEnum: Beginn\r\n";
		for (int i = 0; i < peaks.size(); i++)
			PeakListe += ((Peak) peaks.elementAt(i)).toString() + "\r\n";

		returnValue += PeakListe;
		returnValue += "PeaksEnum: ende\r\n";
		returnValue += "EndObject";

		return returnValue;

	}

}
